import { Vector2, Vector3 } from 'three'

const R = 6378137
const D = Math.PI / 180
const RD = R * D
const r = R / 2
const HPI = Math.PI / 2

export class Projection {
  readonly offset: Vector2
  readonly scale:number
  constructor (center: [number, number], scale: number) {
    const sin = Math.sin(center[1] * D)
    this.offset = new Vector2(RD * center[0], r * Math.log((1 + sin) / (1 - sin)))
    this.scale=scale
  }

  lonToX (lon: number) {
    return RD * lon - this.offset.x
  }

  latToY (lat: number) {
    const sin = Math.sin(lat * D)
    return r * Math.log((1 + sin) / (1 - sin)) - this.offset.y
  }

  altToZ (alt: number) {
    return alt * this.scale
  }

  xToLon (x: number) {
    return (x + this.offset.x) / RD
  }

  yToLat (y: number) {
    return (2 * Math.atan(Math.exp((y + this.offset.y) / R)) - (HPI)) / D
  }

  zToAlt (z: number) {
    return z / this.scale
  }

  project (p: Vector3) {
    p.x = this.lonToX(p.x)
    p.y = this.latToY(p.y)
    p.z = this.altToZ(p.z)
    return p
  }

  unproject (p: Vector3) {
    p.x = this.xToLon(p.x)
    p.y = this.yToLat(p.y)
    p.z = this.zToAlt(p.z)
    return p
  }
}


export const projection=new Projection([120,30],20)